﻿using Microsoft.EntityFrameworkCore;
using SJ.Platform.Common;
using SJ.Platform.EFCore.Model;
using SJ.Platform.EFCore.Model.ProjectManager;
using SJ.Platform.Extend.ModelExtend;
using SJ.Platform.Extend.ModelExtend.ProjectExt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SJ.Platform.EFCore.DBOperation.DBOperation.MySQL.Project
{
    public class Project_Schedule_TaskHandle
    {
        private readonly SJDBContext _context;

        public Project_Schedule_TaskHandle(SJDBContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> CreateAsync(ProjectScheduleTask entity)
        {
            try
            {
                _context.ProjectScheduleTasks.Add(entity);
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>Create", ex);
                return false;
            }
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> BatchCreateAsync(List<ProjectScheduleTask> list)
        {
            try
            {
                int result = 0;
                if (list != null && list.Count > 0)
                {
                    foreach (ProjectScheduleTask entity in list)
                    {
                        _context.ProjectScheduleTasks.Add(entity);
                    }
                    result = await _context.SaveChangesAsync();
                }

                return result == list.Count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>BatchCreateAsync", ex);
                return false;
            }
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(ProjectScheduleTask entity)
        {
            try
            {
                _context.Entry(entity).State = EntityState.Modified;
                await _context.SaveChangesAsync();
                return true;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>Update", ex);
                return false;
            }
        }

        /// <summary>
        /// 更新任务进度
        /// </summary>
        /// <param name="entityExt"></param>
        /// <returns></returns>
        public async Task<bool> UpdateScheduleTaskProgressAsync(List<ProjectScheduleTask> list)
        {
            try
            {
                foreach (var entity in list)
                {
                    // 确保实体的状态是“附加”（Attached），以便进行更新
                    _context.Attach(entity);
                    _context.Entry(entity).Property("Progress").IsModified = true;
                }
                var affectedRows = await _context.SaveChangesAsync();
                return list.Count == affectedRows;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>UpdateScheduleTaskProgressAsync", ex);
                return false;
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Delete(ProjectScheduleTask entity)
        {
            try
            {
                _context.ProjectScheduleTasks.Remove(entity);
                return _context.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>Delete", ex);
                return false;
            }
        }

        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByIdAsync(string id)
        {
            try
            {
                var entity = _context.ProjectScheduleTasks.Find(id);
                if (entity != null)
                {
                    _context.ProjectScheduleTasks.Remove(entity);
                    await _context.SaveChangesAsync();
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>DeleteById", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据父级id删除
        /// </summary>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByPIdAsync(string pId)
        {
            try
            {
                var tasks = await _context.ProjectScheduleTasks.Where(task => task.PId == pId).ToListAsync();
                int count = _context.Database.ExecuteSqlRaw($"delete from project_schedule_task where PId='{pId}';");
                return tasks.Count == count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>DeleteByPIdAsync", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据项目id删除
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteByProjectIdAsync(string projectId)
        {
            try
            {
                var tasks = await _context.ProjectScheduleTasks.AsNoTracking().Where(task => task.ProjectId == projectId).ToListAsync();
                int count = _context.Database.ExecuteSqlRaw($"delete from project_schedule_task where ProjectId='{projectId}';");
                return tasks.Count == count;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>DeleteByProjectIdAsync", ex);
            }
            return false;
        }

        /// <summary>
        /// 根据ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ProjectScheduleTask> GetEntityByIdAsync(string id)
        {
            try
            {
                return await _context.ProjectScheduleTasks.FindAsync(id);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetEntityById", ex);
            }
            return null;
        }

        /// <summary>
        /// 根据需求ID获取任务
        /// </summary>
        /// <param name="rId"></param>
        /// <returns></returns>
        public async Task<ProjectScheduleTask> GetEntityByRIdAsync(string rId)
        {
            try
            {
                return await _context.ProjectScheduleTasks.Where(t => t.RId == rId).FirstAsync();
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetEntityByRIdAsync", ex);
            }
            return null;
        }

        /// <summary>
        /// 根据父级ID获取所有第一级子任务
        /// </summary>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTask>> GetFirstLevelChildTasksByPIdAsync(string pId)
        {
            try
            {
                //任务
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.Where(task => task.PId == pId).OrderBy(info => info.Sort).ToListAsync();
                return tasks;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetFirstLevelChildTasksByPIdAsync", ex);
                return null;
            }
        }

        /// <summary>
        /// 根据父级ID递归获取所有子任务
        /// </summary>
        /// <param name="pId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTaskExtend>> GetDeepChildTasksByPIdAsync(string pId)
        {
            try
            {
                string query = @"WITH RECURSIVE childtasks AS (    
                                    SELECT *
                                    FROM project_schedule_task
                                    WHERE Id = '{0}'  

                                    UNION ALL    

                                    SELECT c.*
                                    FROM project_schedule_task c
                                    INNER JOIN childtasks sc ON c.PId = sc.Id
                                )
                                SELECT * FROM childtasks WHERE Id != '{0}'
                                ";
                query = string.Format(query, pId);
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.FromSqlRaw(query).ToListAsync();
                List<ProjectScheduleTaskExtend> taskExtends = tasks.MapToList<ProjectScheduleTask, ProjectScheduleTaskExtend>();

                //任务对应的负责人
                if (taskExtends != null && taskExtends.Count > 0)
                {
                    foreach (var task in taskExtends)
                    {
                        List<ProjectSchedulePerson> persons = await _context.ProjectSchedulePersons.Where(p => p.TaskId == task.Id).ToListAsync();
                        if (persons != null && persons.Count > 0)
                        {
                            task.Persons = new List<ProjectSchedulePerson>();
                            task.Persons = persons;

                            List<string> personIdList = new List<string>();
                            List<string> personNameList = new List<string>();
                            foreach (var item in persons)
                            {
                                personIdList.Add(item.UserId);
                                personNameList.Add(item.UserName);
                            }
                            task.PersonIds = string.Join(",", personIdList.ToArray());
                            task.PersonNames = string.Join(",", personNameList.ToArray());
                        }
                    }
                }

                return taskExtends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetDeepChildTasksByPIdAsync", ex);
                return null;
            }
        }

        /// <summary>
        /// 获取项目下的第一级子任务 
        /// </summary>
        /// <param name="mId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTask>> GetChildTasksByMIdAsync(string mId)
        {
            try
            {
                //任务
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.Where(task => task.Mid == mId && string.IsNullOrWhiteSpace(task.PId)).OrderBy(info => info.Sort).ToListAsync();
                return tasks;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetChildTasksByProjectIdAsync", ex);
                return null;
            }
        }

        /// <summary>
        /// 根据进度ID获取进度详情
        /// </summary>
        /// <param name="scheduleId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTaskExtend>> GetSchedulesByScheduleIdAsync(string scheduleId)
        {
            try
            {
                string query = @"WITH RECURSIVE schedules AS (    
                                    SELECT *
                                    FROM project_schedule_task
                                    WHERE Id = '{0}'  

                                    UNION ALL    

                                    SELECT t.*
                                    FROM project_schedule_task t
                                    INNER JOIN schedules rt ON t.PId = rt.Id
                                )
                                SELECT * FROM schedules  ORDER BY sort;
                                ";
                query = string.Format(query, scheduleId);
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.FromSqlRaw(query).ToListAsync();
                List<ProjectScheduleTaskExtend> taskExtends = tasks.MapToList<ProjectScheduleTask, ProjectScheduleTaskExtend>();

                return taskExtends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Requirement_InfoHandle=>GetRequirementsAndFeaturesByRequirementIdAsync", ex);
                return null;
            }
        }


        /// <summary>
        /// 根据项目ID获取任务
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTaskExtend>> GetSchedulesByProjectIdAsync(string projectId)
        {
            try
            {
                //任务
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.Where(task => task.ProjectId == projectId).OrderBy(info => info.Sort).ToListAsync();
                List<ProjectScheduleTaskExtend> taskExtends = tasks.MapToList<ProjectScheduleTask, ProjectScheduleTaskExtend>();

                //任务对应的负责人
                if (taskExtends != null && taskExtends.Count > 0)
                {
                    foreach (var task in taskExtends)
                    {
                        List<ProjectSchedulePerson> persons = await _context.ProjectSchedulePersons.Where(p => p.TaskId == task.Id).ToListAsync();
                        if (persons != null && persons.Count > 0)
                        {
                            task.Persons = new List<ProjectSchedulePerson>();
                            task.Persons = persons;

                            List<string> personIdList = new List<string>();
                            List<string> personNameList = new List<string>();
                            foreach (var item in persons)
                            {
                                personIdList.Add(item.UserId);
                                personNameList.Add(item.UserName);
                            }
                            task.PersonIds = string.Join(",", personIdList.ToArray());
                            task.PersonNames = string.Join(",", personNameList.ToArray());
                        }
                    }
                }

                return taskExtends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetSchedulesByProjectIdAsync", ex);
                return null;
            }
        }

        /// <summary>
        /// 获取负责人下的所有项目任务
        /// </summary>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <param name="userId"></param>
        /// <param name="cprm"></param>
        /// <returns></returns>
        public async Task<(List<ProjectScheduleTask> tasks, int count)> GetProjectScheduleTasksAsync(int pageNumber, int pageSize, string userId, Expression<Func<ProjectScheduleTask, bool>> cprm = null)
        {
            try
            {
                var query = from person in _context.ProjectSchedulePersons
                            join task in _context.ProjectScheduleTasks on person.TaskId equals task.Id
                            join main in _context.ProjectScheduleMains on task.Mid equals main.Id
                            where person.UserId == userId && main.Status == 5
                            select task;
                //select new ProjectScheduleTaskExtend
                //{
                //    Id = task.Id,
                //    Mid = task.Mid,
                //    TaskName = task.TaskName,
                //    ProjectId = task.ProjectId,
                //    PId = task.PId,
                //    PName = task.PName,
                //    RId = task.RId,
                //    RName = task.RName,
                //    Mark = task.Mark,
                //    StartTime = task.StartTime,
                //    EndTime = task.EndTime,
                //    Progress = task.Progress,
                //    Sort = task.Sort,
                //    AddTime = task.AddTime,
                //    AddUserId = task.AddUserId,
                //    EditTime = task.EditTime,
                //    EditUserId = task.EditUserId
                //};
                // 如果提供了查询条件，则应用它
                if (cprm != null)
                {
                    query = query.Where(cprm);
                }

                // 总条数
                int count = await query.CountAsync();

                // 应用分页
                var skip = (pageNumber - 1) * pageSize;
                var pagedQuery = query.OrderByDescending(order => order.AddTime).Skip(skip).Take(pageSize);

                // 执行查询并返回结果
                var tasks = await pagedQuery.ToListAsync();

                return (tasks, count);
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetProjectScheduleTasksAsync", ex);
            }
            return (null, 0);
        }

        /// <summary>
        /// 根据项目ID获取进度计划树
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<List<ProjectScheduleTaskExtend>> GetProjectScheduleTreeByProjectIdAsync(string projectId)
        {
            try
            {
                //需求
                List<ProjectScheduleTask> tasks = await _context.ProjectScheduleTasks.Where(info => info.ProjectId == projectId).OrderBy(info => info.Sort).ToListAsync();
                List<ProjectScheduleTaskExtend> taskExtends = tasks.MapToList<ProjectScheduleTask, ProjectScheduleTaskExtend>();

                List<ProjectScheduleTaskExtend> extends = taskExtends.Where(info => string.IsNullOrWhiteSpace(info.PId)).ToList();
                BuildLevel(extends, taskExtends);
                return extends;
            }
            catch (Exception ex)
            {
                LogManager.WriteError("Project_Schedule_TaskHandle=>GetProjectScheduleTreeByProjectIdAsync", ex);
                return null;
            }
        }

        /// <summary>
        /// 生成进度计划层级树
        /// </summary>
        /// <param name="extends"></param>
        /// <param name="infoSource"></param>
        /// <param name="featureSource"></param>
        private void BuildLevel(List<ProjectScheduleTaskExtend> extends, List<ProjectScheduleTaskExtend> taskSource)
        {
            foreach (var item in extends)
            {
                //需求层级
                var child = taskSource.Where(info => info.PId == item.Id);
                if (child != null && child.Count() > 0)
                {
                    if (item.ChildTasks == null)
                    {
                        item.ChildTasks = new List<ProjectScheduleTaskExtend>();
                    }

                    item.ChildTasks = child.ToList();
                    BuildLevel(item.ChildTasks, taskSource);
                }
            }
        }
    }
}
